package com.Modular.pdf_Util;

import org.docx4j.Docx4J;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.finders.ClassFinder;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFont;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.jaxb.Context;
import org.docx4j.model.datastorage.migration.VariablePrepare;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.*;

import com._Config.Model.errorLogModel;

import java.io.*;
import java.math.BigInteger;
import java.nio.file.Paths;
import java.util.*;

public class PDF_utils {

    /**
     * 为了减少引入数据库。
     * 
     * 
     * com.Modular.pdf_Util.examplesPDF 
     * 下面的事例的所有数据库查询
     * 引入了异常插件的数据库表，用来演示
     * 
     * 
     * @param args
     */
    public static void main(String[] args) {
        String dir = System.getProperty("user.dir");//获取系统变量
        String outPath = String.format("%s%s%s", dir, "/webapp/WEB-INF/template/temp/", "test.pdf");
        try {
        	//为了减少引入数据库，此处引入了异常插件的数据库表，用来演示
        	errorLogModel huiyi = new errorLogModel();
            huiyi.set("GongSiMingCheng", "test");
            huiyi.set("HuiYiLeiXing", "HuiYiLeiXing");
            huiyi.set("HuiYiDiDian", "HuiYiDiDian");
            Map<String, String> data = new HashMap<>();
            data.put("QiYeMingCheng", huiyi.getStr("GongSiMingCheng"));
            //单表单
//            buildPdf("模板1.docx", outPath, data);
            List<Map<String, Object>> mapList = new ArrayList<>();
            for (int i = 0; i < 2; i++) {
                Map<String, Object> map = new HashMap<>();
                map.put("BuMenMingCheng", "部门" + i);
                map.put("XingMing", "姓名" + i);
                mapList.add(map);
            }
            //单表格
//            buildPdf("模板2.docx", outPath, mapList);
            //表单
//            buildPdf("模板3.docx", outPath,data);
            //表单+表格
                        buildPdf("模板4.docx", outPath,data,mapList);

            List<Map<String, Object>> mapList2 = new ArrayList<>();
            for (int i = 0; i < 2; i++) {
                Map<String, Object> map = new HashMap<>();
                map.put("BuMenMingCheng", "b部门" + i);
                map.put("XingMing", "b姓名" + i);
                mapList2.add(map);
            }
            //表单+表格+表格
//            buildPdf("模板5.docx", outPath,data,mapList,mapList2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 一表单+一表格
     *
     * @param tempFileName 模板名称
     * @param outPath      输出路径
     * @param mapData      表单数据
     * @param dataList     表格数据
     * @throws Exception
     */
    public static void buildPdf(String tempFileName,
                                String outPath, Map<String, String> mapData, List<Map<String, Object>> ...dataList) throws Exception {
        String dir = System.getProperty("user.dir");
        String fontDir = String.format("%s%s", dir, "/webapp/WEB-INF/template/simhei.ttf");
        String inputFile = String.format("%s%s%s", dir, "/webapp/WEB-INF/template/", tempFileName);
        PDF_utils.buildPdf(inputFile, outPath, fontDir, mapData, 1,dataList);
    }

    /**
     * 一表单+一表格
     *
     * @param tempFileName 模板名称
     * @param outPath      输出路径
     * @param mapData      表单数据
     * @param dataList     表格数据
     * @param startRow    开始行数
     * @throws Exception
     */
    public static void buildPdf(String tempFileName,
                                String outPath, Map<String, String> mapData,int startRow, List<Map<String, Object>> ...dataList) throws Exception {
        String dir = System.getProperty("user.dir");
        String fontDir = String.format("%s%s", dir, "/webapp/WEB-INF/template/simhei.ttf");
        String inputFile = String.format("%s%s%s", dir, "/webapp/WEB-INF/template/", tempFileName);
        PDF_utils.buildPdf(inputFile, outPath, fontDir, mapData, startRow,dataList);
    }

    /**
     * 单表单（无多行数据）
     *
     * @param tempFileName 模板名称
     * @param outPath      输出路径
     * @param mapData      表单填充数据
     * @throws Exception
     */
    public static void buildPdf(String tempFileName,
                                String outPath, Map<String, String> mapData) throws Exception {
        String dir = System.getProperty("user.dir");
        String fontDir = String.format("%s%s", dir, "/webapp/WEB-INF/template/simhei.ttf");
        String inputFile = String.format("%s%s%s", dir, "/webapp/WEB-INF/template/", tempFileName);
        PDF_utils.buildPdf(inputFile, outPath, fontDir, mapData,1);
    }

    /**
     * 单表格(多行数据)
     *
     * @param tempFileName 模板名称
     * @param outPath      输出路径
     * @param dataList     表格填充数据
     * @throws Exception
     */
    public static void buildPdf(String tempFileName,
                                String outPath, List<Map<String, Object>> dataList) throws Exception {
        String dir = System.getProperty("user.dir");
        String fontDir = String.format("%s%s", dir, "/webapp/WEB-INF/template/simhei.ttf");
        String inputFile = String.format("%s%s%s", dir, "/webapp/WEB-INF/template/", tempFileName);
        PDF_utils.buildPdf(inputFile, outPath, fontDir, null, 1,dataList);
    }

    /**
     * 加载模板并替换数据
     *
     * @param inputDir  输入模板
     * @param outputDir 输出文件
     * @param data      第一个表格
     * @param dataList  第二个表格
     * @throws Exception
     */
    public static void buildPdf(String inputDir, String outputDir, String fontDir,
                                Map<String, String> data,int startRow,
                                List<Map<String, Object>>... dataList) throws Exception {
        final String TEMPLATE_NAME = inputDir;
        InputStream templateInputStream = new FileInputStream(TEMPLATE_NAME);
        //加载模板文件并创建WordprocessingMLPackage对象
        WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(templateInputStream);

        String fontFamily = "simhei";
        Mapper fontMapper = new IdentityPlusMapper();
        wordMLPackage.setFontMapper(fontMapper);
        PhysicalFonts.addPhysicalFont(Paths.get(fontDir).toUri());
        PhysicalFont simsunFont = PhysicalFonts.get(fontFamily);
        fontMapper.put(fontFamily, simsunFont);
        RFonts rfonts = Context.getWmlObjectFactory().createRFonts(); //設置文件默認字體
        rfonts.setAsciiTheme(null);
        rfonts.setAscii(fontFamily);
        wordMLPackage.getMainDocumentPart().getPropertyResolver()
                .getDocumentDefaultRPr().setRFonts(rfonts);


        CTBorder ctBorder = new CTBorder();//Docx4jUtils.buildTableBorder(borderStyle);
        ctBorder.setColor("auto");
        ctBorder.setSpace(BigInteger.valueOf(0));
        ctBorder.setShadow(true);
        ctBorder.setFrame(true);
        ctBorder.setSz(BigInteger.valueOf(6));
        ctBorder.setVal(STBorder.SINGLE);
        TblBorders tblBorders = new TblBorders();
        tblBorders.setLeft(ctBorder);
        tblBorders.setRight(ctBorder);
        tblBorders.setTop(ctBorder);
        tblBorders.setBottom(ctBorder);
        tblBorders.setInsideH(ctBorder);
        tblBorders.setInsideV(ctBorder);

//        HpsMeasure fontSize = new HpsMeasure();
//        fontSize.setVal(BigInteger.valueOf(30));
//        ObjectFactory factory = Context.getWmlObjectFactory();
//        RPr rpr=factory.createRPr();
//        rpr.setSz(fontSize);
//        rpr.setSzCs(fontSize);
//        BooleanDefaultTrue bold = factory.createBooleanDefaultTrue();
//        bold.setVal(true);
//        rpr.setB(bold);
//        R r = factory.createR();
//        r.setRPr(rpr);
        //构造循环列表的数据
        ClassFinder find = new ClassFinder(Tbl.class);
        new TraversalUtil(wordMLPackage.getMainDocumentPart().getContent(), find);
        if (dataList != null && dataList.length > 0) {
//            Tbl table;
//            int tableSize = find.results.size();
//            if(tableSize>1) {
//                table = (Tbl) find.results.get(1);// 第二个表格
//            }else{
//                table = (Tbl) find.results.get(0);// 第一个表格
//            }
            for (int i = 0; i < dataList.length; i++) {
                Tbl table;
                int k=i;
                if(data!=null&&find.results.size()>1){
                    k+=1;
                }
                table = (Tbl) find.results.get(k);// 第一个表格
                table.getTblPr().setTblBorders(tblBorders);
                Tr dynamicTr = (Tr) table.getContent().get(startRow);//第二行约定为模板 从第几行开始、删除第几行
                String dynamicTrXml = XmlUtils.marshaltoString(dynamicTr);//获取模板行的xml数据
                for (Map<String, Object> dataMap : dataList[i]) {
                    Tr newTr = (Tr) XmlUtils.unmarshallFromTemplate(dynamicTrXml, dataMap);//填充模板行数据
                    newTr.setTblPrEx(new CTTblPrEx());
                    newTr.getTblPrEx().setTblBorders(tblBorders);
                    table.getContent().add(newTr);
                }
                table.getTblPr().setTblBorders(tblBorders);
                //删除模板行的占位行
                table.getContent().remove(startRow);
            }

        }
        //替换
        MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
        VariablePrepare.prepare(wordMLPackage);
        if (data != null)
            documentPart.variableReplace(data);

        OutputStream outputStream = new FileOutputStream(outputDir);
        try {
            Docx4J.toPDF(wordMLPackage, outputStream);
        } finally {
            outputStream.close();
            templateInputStream.close();
        }
    }

}
